LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;


entity multiplicador is

	port (
		multiplicando : in std_logic_vector(31 downto 0);
		multiplicador : in std_logic_vector(31 downto 0);
		saidaHI : out std_logic_vector(31 downto 0);
		saidaLO : out std_logic_vector(31 downto 0);
		multControl : in std_logic;
		finishMultControl : out std_logic;
		resultadoCopia : out std_logic_vector(63 downto 0);
		contadorCopia : out std_logic_vector(5 downto 0);
		clk : in std_logic
	);
end multiplicador;

architecture arc_multiplicador of multiplicador is
	type estados is (atribuicao, iteracao, fim);
	signal status: estados;

begin	

	process(clk)
			
			variable resultado : std_logic_vector(63 downto 0);
			variable multiplicandoTemp :  std_logic_vector(31 downto 0);
			variable contador : std_logic_vector(5 downto 0); -- 6 bits para a contagem de ciclo como um todo
			variable sinal : std_logic;

						
		begin
			if(clk'event and clk = '1') then
				if(multControl = '1') then
					case status is
						when atribuicao =>
						
							if(multiplicador(31) /= multiplicando(31)) then
								sinal := '1';
							else
								sinal := '0';
							end if;
						
							if(multiplicador(31) = '0') then
								resultado(31 downto 0) := multiplicador;								
							else
								resultado(31 downto 0) := (not multiplicador) + 1; 
							end if;
							
							if(multiplicando(31) = '0') then
								multiplicandoTemp := multiplicando;
							else
								multiplicandoTemp:= (not multiplicando) + 1; 
							end if;
							

							resultado(63 downto 32) := "00000000000000000000000000000000";
							contador := "000000";
							resultadoCopia <= resultado;
							contadorCopia <= contador;		
							status <= iteracao;
							finishMultControl <= '0';
							
						when iteracao =>
							if(resultado(0) = '1') then
								resultado(63 downto 32) := resultado(63 downto 32) + multiplicandoTemp;
							end if;
							
							resultado(62 downto 0) := resultado(63 downto 1);
							resultado(63) := sinal;
							resultadoCopia <= resultado;	
														
							contador := contador + 1;							
							contadorCopia <= contador;
														
							if(contador = 31) then
								status <= fim;																																
							end if;

							
						when fim =>
							resultado(62 downto 0) := resultado(63 downto 1);		
							resultado(63) := sinal;
							resultadoCopia <= resultado;	
							status <= atribuicao;
							finishMultControl <= '1';
							if(sinal = '1') then
								resultado(31 downto 0) := (not resultado(31 downto 0)) + 1; 
							end if;
													
							saidaHi <= resultado(63 downto 32);	
							saidaLO <= resultado(31 downto 0);	
							resultadoCopia <= resultado;	
							contador := contador + 1;
							contadorCopia <= contador;					
						
					end case;
				end if;
			end if;
	end process;
	
end arc_multiplicador;
			
			
	
		
		
		
		